package com.ruoyi.flowable.listener;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.flowable.domain.SysDeployForm;
import com.ruoyi.flowable.service.ISysDeployFormService;
import com.ruoyi.framework.websocket.WebSocketService;
import com.ruoyi.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.identitylink.api.IdentityLink;
import org.flowable.identitylink.service.impl.persistence.entity.IdentityLinkEntity;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * 任务完成全局监听器
 */
@Component
@Slf4j
public class FlowableGlobalTaskListener extends AbstractFlowableEngineEventListener {
    @Autowired
    private ISysDeployFormService sysDeployFormService;
    @Autowired
    protected RepositoryService repositoryService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private ISysUserService userService;

    /**
     * 任务创建时处理业务
     *
     * @param event
     */
    @Override
    protected void taskCreated(FlowableEngineEntityEvent event) {
        System.out.println("进入taskCreated监听器……");
        //流程任务创建
        String processInstanceId = event.getProcessInstanceId();
        Map<String, Object> variables = runtimeService.getVariables(processInstanceId);
        variables.put("PROCESS_STATUS", "TASK");

        TaskEntity taskEntity = (TaskEntity) event.getEntity();
        variables.put("taskKey", taskEntity.getTaskDefinitionKey());
        variables.put("taskName", taskEntity.getName());
        //业务流程回调
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(event.getProcessDefinitionId()).singleResult();
        HttpClientCallback(processDefinition, variables);
        /* 处理流程审批人begin*/
        //发送系统消息
        List<String> userList = new ArrayList<>();

        //指定审批人
        if (Objects.nonNull(taskEntity.getAssignee())) {
            userList.add(taskEntity.getAssignee());
        }
        //候选审批
        List<IdentityLinkEntity> identityLinkList = taskEntity.getIdentityLinks();
        if (CollectionUtils.isNotEmpty(identityLinkList)) {
            for (IdentityLink identityLink : identityLinkList) {
                if ("candidate".equals(identityLink.getType())) {
                    if (StringUtils.isNotBlank(identityLink.getUserId())) {
                        userList.add(identityLink.getUserId());
                    }
                    if (StringUtils.isNotBlank(identityLink.getGroupId())) {
                        List<SysUser> sysUserList = userService.selectUserListByRoleId(Long.parseLong(identityLink.getGroupId()));
                        for (SysUser user : sysUserList) {
                            userList.add(user.getUserId().toString());
                        }
                    }
                }
            }
        }
        //去除重复用户
        HashSet hashSet = new HashSet(userList);
        userList.clear();
        userList.addAll(hashSet);
        /* 处理流程审批人end*/
        //循环推送消息
        for (String user : userList) {
            JSONObject json = new JSONObject();
            json.put("title", "审批");
            json.put("uri", "/flowable/task/record/index?procInsId=" + processInstanceId + "&executionId=" + taskEntity.getExecutionId() + "&deployId=" + processDefinition.getDeploymentId() + "&taskId=" + taskEntity.getId() + "&finished=true");
            StringBuffer htmlMessage = new StringBuffer("您有新的" + processDefinition.getName() + "审批任务,请及时处理！");
            htmlMessage.append(" <button class=\"el-button el-button--primary el-button--mini\" type=\"button\" >办理</button>");
            json.put("message", htmlMessage);
            //发送消息到面板
            //remoteUserService.pushMessage("新的审批任务提醒", "您有新的" + processDefinition.getName() + "审批任务,请及时处理！", Long.parseLong("1"), Long.parseLong(user));
            //发送消息提醒
            WebSocketService.sendMessage(user, json.toString());
            //发送钉钉消息
        }
    }

    @Override
    protected void processCompleted(FlowableEngineEntityEvent event) {
        System.out.println("进入taskCreated监听器……");
        String processInstanceId = event.getProcessInstanceId();
        Map<String, Object> variables = runtimeService.getVariables(processInstanceId);
        variables.put("PROCESS_STATUS", "END");
        //业务流程回调
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(event.getProcessDefinitionId()).singleResult();
        HttpClientCallback(processDefinition, variables);
        //发送系统消息
        JSONObject json = new JSONObject();
        json.put("title", "审批完成");
        StringBuffer htmlMessage = new StringBuffer("您发起的" + processDefinition.getName() + "审批已完成,请知晓！");
        json.put("message", htmlMessage);
        //发送消息到面板
        //remoteUserService.pushMessage("审批任务完成提醒", "您发起的" + processDefinition.getName() + "审批已完成,请知晓！", Long.parseLong("1"), Long.parseLong(variables.get("INITIATOR").toString()));
        //发送消息提醒
        WebSocketService.sendMessage(variables.get("INITIATOR").toString(), json.toString());

    }

    /**
     * 执行任务回调数据推送
     *
     * @param processDefinitionId
     * @param variables
     */
    private void HttpClientCallback(ProcessDefinition processDefinition, Map<String, Object> variables) {
        SysDeployForm sysDeployForm = sysDeployFormService.selectSysDeployFormByDeployID(processDefinition.getDeploymentId());
        if (sysDeployForm != null && sysDeployForm.getBusinessAPI() != null && sysDeployForm.getType().equals("business")) {
            Map<String, String> httpData = new HashMap<>();
            for (Map.Entry<String, Object> entry : variables.entrySet()) {
                httpData.put(entry.getKey(), entry.getValue().toString());
            }
            try {
                HttpUtils.sendPost(sysDeployForm.getBusinessAPI(), JSON.toJSONString(httpData));
                log.info("消息回调推送成功");
            } catch (Exception e) {
                log.info("推送任务状态：" + e.getMessage());
            }
        }
    }
}

